package com.iakuil.app.common.core.util;

import com.iakuil.app.common.core.DictEnum;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.lang.Nullable;

import java.util.*;

/**
 * 字典枚举工具类
 *
 * @author Kai
 */
@Slf4j
@UtilityClass
public class DictEnumUtils {
    private static final MultiValuedMap<Class<? extends DictEnum<?>>, DictEnum<?>> DICT_CACHE = new HashSetValuedHashMap<>();

    /**
     * 根据字典类型获取字典枚举列表
     *
     * @param clazz 字典类型
     * @return 字典枚举
     */
    public static List<DictEnum<?>> getMembers(Class<? extends DictEnum<?>> clazz) {
        if (clazz == null) {
            return Collections.emptyList();
        }

        Collection<DictEnum<?>> dictEnums = DICT_CACHE.get(clazz);
        if (dictEnums.isEmpty()) {
            dictEnums = Arrays.asList(clazz.getEnumConstants());
            DICT_CACHE.putAll(clazz, dictEnums);
        }

        return dictEnums.stream().toList();
    }

    /**
     * 根据字典类型和字典值获取字典枚举
     *
     * @param clazz 字典类型
     * @param label 字典标签
     * @return 字典枚举
     */
    @Nullable
    public static DictEnum<?> fromLabel(Class<? extends DictEnum<?>> clazz, String label) {
        List<DictEnum<?>> targets = fromLabels(clazz, label);
        return CollectionUtils.isEmpty(targets) ? null : targets.get(0);
    }

    /**
     * 根据字典类型和字典值获取字典枚举列表
     *
     * @param clazz  字典类型
     * @param labels 字典标签列表
     * @return 字典枚举
     */
    public static List<DictEnum<?>> fromLabels(Class<? extends DictEnum<?>> clazz, String... labels) {
        if (clazz == null || labels == null) {
            return Collections.emptyList();
        }

        Collection<DictEnum<?>> dictEnums = DICT_CACHE.get(clazz);
        if (dictEnums == null) {
            dictEnums = Arrays.asList(clazz.getEnumConstants());
            DICT_CACHE.putAll(clazz, dictEnums);
        }

        List<DictEnum<?>> targets = new ArrayList<>();
        for (DictEnum<?> dictEnum : dictEnums) {
            if (ArrayUtils.contains(labels, dictEnum.getLabel())) {
                targets.add(dictEnum);
            }
        }
        return targets;
    }

    /**
     * 根据字典类型和字典值获取字典枚举
     *
     * @param clazz 字典类型
     * @param value 字典值
     * @return 字典枚举
     */
    @Nullable
    public static DictEnum<?> fromValue(Class<? extends DictEnum<?>> clazz, Object value) {
        List<DictEnum<?>> targets = fromValues(clazz, value);
        return CollectionUtils.isEmpty(targets) ? null : targets.get(0);
    }

    /**
     * 根据字典类型和字典值获取字典列表
     *
     * @param clazz  字典类型
     * @param values 字典值列表
     * @return 字典枚举列表
     */
    public static List<DictEnum<?>> fromValues(Class<? extends DictEnum<?>> clazz, Object... values) {
        if (clazz == null || values == null) {
            return Collections.emptyList();
        }

        Collection<DictEnum<?>> dictEnums = DICT_CACHE.get(clazz);
        if (dictEnums == null) {
            dictEnums = Arrays.asList(clazz.getEnumConstants());
            DICT_CACHE.putAll(clazz, dictEnums);
        }

        List<DictEnum<?>> targets = new ArrayList<>();
        for (DictEnum<?> dictEnum : dictEnums) {
            if (ArrayUtils.contains(values, dictEnum.getValue())) {
                targets.add(dictEnum);
            }
        }

        return targets;
    }
}
